﻿/*
 * 版权所有 2024 Rapid Software LLC
 * 
 * 根据 Apache 许可证 2.0 版（“许可证”）获得许可;
 * 除非符合许可，否则您不得使用此文件.
 * 您可以在以下位置获取许可证的副本
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * 除非适用法律要求或书面同意，否则根据本许可分发的软件按“原样”分发，
 * 不提供任何明示或暗示的保证或条件。
 * 请参阅许可证，了解许可证下管理权限和限制的特定语言。
 * 
 * 
 * Product  : Rapid SCADA
 * Module   : ScadaCommCommon
 * Summary  : Creates driver instances
 * 
 * Author   : Mikhail Shiryaev
 * Created  : 2020
 * Modified : 2023
 * 
 * Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License
*/ 
using Scada.Lang;
using System;
using System.IO;
using System.Reflection;

namespace Scada.Comm.Drivers
{
    /// <summary>
    /// Creates driver instances.
    /// 创建驱动程序实例  获取驱动逻辑部分和界面部分
    /// <para>Создает экземпляры драйверов.</para>
    /// </summary>
    public static class DriverFactory
    {
        /// <summary>
        /// 获取驱动程序逻辑的新实例。
        /// </summary>
        public static bool GetDriverLogic(string directory, string driverCode, ICommContext commContext,
            out DriverLogic driverLogic, out string message)
        {
            //组合出程序集路径
            string fileName = Path.Combine(directory, driverCode + ".Logic.dll");
            //获取类名
            string typeName = string.Format("Scada.Comm.Drivers.{0}.Logic.{0}Logic", driverCode);

            try
            {
                if (File.Exists(fileName))//检查程序集是否存在
                {
                    //加载程序集
                    Assembly assembly = Assembly.LoadFrom(fileName);
                    //尝试获取类名为typeName的对象的type
                    Type type = assembly.GetType(typeName, true);
                    //创建这个对象，并强转换为DriverLogic类型 这是该方法获取的主要对象
                    driverLogic = (DriverLogic)Activator.CreateInstance(type, commContext);//如果存在则创建实例
                    //驱动code，驱动版本，驱动路径 组合到message字段输出
                    message = string.Format(Locale.IsRussian ?
                        "Драйвер {0} {1} загружен из файла {2}" :
                        "Driver {0} {1} loaded from file {2}",
                        driverCode, driverLogic.Version, fileName);
                    return true;//返回
                }
                else//程序集不存在，返回未找到程序集
                {
                    driverLogic = null;
                    message = string.Format(Locale.IsRussian ?
                        "Невозможно создать логику драйвера {0}. Файл {1} не найден" :
                        "Unable to create driver logic {0}. File {1} not found", driverCode, fileName);
                    return false;
                }
            }
            catch (Exception ex)//异常
            {
                driverLogic = null;
                message = string.Format(Locale.IsRussian ?
                    "Ошибка при создании логики драйвера {0} типа {1} из файла {2}: {3}" :
                    "Error creating driver logic {0} of type {1} from file {2}: {3}",
                    driverCode, typeName, fileName, ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 获取驱动程序用户界面的新实例。
        /// </summary>
        public static bool GetDriverView(string directory, string driverCode,
            out DriverView driverView, out string message)
        {
            //组合
            string fileName = Path.Combine(directory, driverCode + ".View.dll");
            string typeName = string.Format("Scada.Comm.Drivers.{0}.View.{0}View", driverCode);

            try
            {
                if (File.Exists(fileName))//判断存在
                {

                    //反射实体类
                    Assembly assembly = Assembly.LoadFrom(fileName);
                    Type type = assembly.GetType(typeName, true);
                    driverView = (DriverView)Activator.CreateInstance(type);

                    //成功返回
                    message = string.Format(Locale.IsRussian ?
                        "Загружен интерфейс драйвера {0} {1} из файла {2}" :
                        "Loaded driver interface {0} {1} from file {2}",
                        driverCode, driverView.Version, fileName);
                    return true;
                }
                else//程序集不存在
                {
                    driverView = null;
                    message = string.Format(Locale.IsRussian ?
                        "Невозможно создать интерфейс драйвера {0}. Файл {1} не найден" :
                        "Unable to create driver interface {0}. File {1} not found", driverCode, fileName);
                    return false;
                }
            }
            catch (Exception ex)//异常
            {
                driverView = null;
                message = string.Format(Locale.IsRussian ?
                    "Ошибка при создании интерфейса драйвера {0} типа {1} из файла {2}: {3}" :
                    "Error creating driver interface {0} of type {1} from file {2}: {3}",
                    driverCode, typeName, fileName, ex.Message);
                return false;
            }
        }
    }
}
